package br.ufpb.di.ppgi.negocio.modelo.proposta;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.hibernate.validator.NotNull;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import br.com.caelum.vraptor.interceptor.multipart.UploadedFile;
import br.ufpb.di.ppgi.negocio.modelo.aluno.Aluno;
import br.ufpb.di.ppgi.negocio.modelo.usuario.Usuario;
import br.ufpb.di.ppgi.persistencia.listeners.PropostaListener;

@Entity
@EntityListeners(PropostaListener.class)
public class Proposta implements Serializable {
	private static final long serialVersionUID = 2925455401638002302L;
	private static final Logger LOGGER = LoggerFactory.getLogger(Proposta.class);

	@Id @GeneratedValue private Long id;
	
	@ManyToOne(optional=false)
	private Aluno aluno;
	
	@ManyToOne(optional=false)
	private Usuario orientador;
	
	@ManyToOne(optional=false)
	private Usuario professor1;
	
	@ManyToOne(optional=false)
	private Usuario professor2;
	
	@NotNull @Temporal(TemporalType.TIMESTAMP)
	private Date data_cadastro = new Date();
	
	@Temporal(TemporalType.TIMESTAMP)
	private Date data_proposta;

	@NotNull private String titulo;
	private String resumo;
	
	@NotNull private PropostaStatus status = PropostaStatus.PENDENTE;
	@NotNull private String file_path;
	@NotNull private String local;
	
	@Transient private List<Usuario> colegiados;
	@Transient private List<Usuario> professores; 
	
	public Proposta() {
		
	}

	public Proposta(Long id, Aluno aluno, Usuario orientador,
			Usuario professor1, Usuario professor2, Date data_cadastro,
			Date data_proposta, String titulo, String resumo,
			PropostaStatus status, String file_path, String local) {
		super();
		this.id = id;
		this.aluno = aluno;
		this.orientador = orientador;
		this.professor1 = professor1;
		this.professor2 = professor2;
		this.data_cadastro = data_cadastro;
		this.data_proposta = data_proposta;
		this.titulo = titulo;
		this.resumo = resumo;
		this.status = status;
		this.file_path = file_path;
		this.local = local;
	}



	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public Aluno getAluno() {
		return aluno;
	}
	public void setAluno(Aluno aluno) {
		this.aluno = aluno;
	}
	public Date getData_cadastro() {
		return data_cadastro;
	}
	public void setData_cadastro(Date data_cadastro) {
		this.data_cadastro = data_cadastro;
	}
	public Date getData_proposta() {
		return data_proposta;
	}
	public void setData_proposta(Date data_proposta) {
		this.data_proposta = data_proposta;
	}
	public String getTitulo() {
		return titulo;
	}

	public void setTitulo(String titulo) {
		this.titulo = titulo;
	}

	public String getResumo() {
		return resumo;
	}

	public void setResumo(String resumo) {
		this.resumo = resumo;
	}
	
	public PropostaStatus getStatus() {
		return status;
	}

	public void setStatus(PropostaStatus status) {
		this.status = status;
	}

	public String getFile_path() {
		return file_path;
	}

	public void setFile_path(String file_path) {
		this.file_path = file_path;
	}
	
	public Usuario getOrientador() {
		return orientador;
	}

	public void setOrientador(Usuario orientador) {
		this.orientador = orientador;
	}

	public Usuario getProfessor1() {
		return professor1;
	}

	public void setProfessor1(Usuario professor1) {
		this.professor1 = professor1;
	}

	public Usuario getProfessor2() {
		return professor2;
	}

	public void setProfessor2(Usuario professor2) {
		this.professor2 = professor2;
	}

	public String getLocal() {
		return local;
	}

	public void setLocal(String local) {
		this.local = local;
	}

	@Override
	public int hashCode() {
		int hash = 0;
		hash += aluno == null ? 0 : aluno.hashCode();
		hash += data_cadastro  == null ? 0 : data_cadastro.hashCode();
		hash += data_proposta  == null ? 0 : data_proposta.hashCode();
		return hash;
	}

	@Override
	public boolean equals(Object object) {
		if(!(object instanceof Proposta)) {
			return false;
		}
		Proposta other = (Proposta) object;
		if(this.id != other.id)
			return false;
		if(this.aluno == null || !this.aluno.equals(other.aluno))
			return false;
		if(this.data_cadastro == null || !this.data_cadastro.equals(other.data_cadastro))
			return false;
		if(this.data_proposta == null || !this.data_proposta.equals(other.data_proposta))
			return false;
		return true;
	}

	public void updateHoraMinuto(int hora, int minuto) {
		DateTime dt = new DateTime(data_proposta == null ? new Date().getTime() : data_proposta.getTime());
		this.data_proposta = dt.plusHours(hora).plusMinutes(minuto).toDate();
	}

	public void saveAnexo(UploadedFile anexo, String baseDir) {
		String filename = String.valueOf(System.currentTimeMillis()) + "." +FilenameUtils.getExtension(anexo.getFileName()); 
		this.file_path = baseDir + filename;
		
		File dir = new File(baseDir);
		dir.mkdir();
		
		File file = new File(file_path);

		InputStream stream = anexo.getFile();
		try {
			file.createNewFile();
			IOUtils.copy(stream,new FileOutputStream(file));
		} catch (IOException e) {
			LOGGER.debug("Falha ao tentar salvar o anexo da proposta. "+this.file_path, e);
		}
	}
	
	public List<Usuario> getColegiados() {
		return colegiados;
	}

	public void setColegiados(List<Usuario> colegiados) {
		this.colegiados = colegiados;
	}

	public List<Usuario> getProfessores() {
		return professores;
	}

	public void setProfessores(List<Usuario> professores) {
		this.professores = professores;
	}

	private static final SimpleDateFormat sdf = new SimpleDateFormat("dd 'de' MMMM 'de' yyyy");

	public String textoAtaParticipacao() {
		return new StringBuilder("Declaro para os devidos fins que o professor ")
			.append(orientador.getNome())
			.append(", orientador, ")
			.append(professor1.getNome())
			.append(" e ")
			.append(professor2.getNome())
			.append(" participaram da Banca Examinadora da Defesa de Dissertação de Mestrado do aluno ")
			.append(aluno.getNome())
			.append(", sob o título: ")
			.append(titulo)
			.append(", no Programa de Pós-Graduação em Informática, nível Mestrado, do ")
			.append("Departamento de Informática da Universidade Federal da Paraíba, no dia ")
			.append(sdf.format(data_proposta))
			.toString();
	}
	
}
